package com.fengxu.gamescript.ui.float

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.PixelFormat
import android.os.Build
import android.view.*
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.animation.doOnEnd
import androidx.core.view.isVisible
import com.fengxu.gamescript.R
import com.fengxu.gamescript.data.Conf
import com.fengxu.gamescript.data.GlobalData
import com.fengxu.gamescript.ui.base.BaseActivity
import com.fengxu.gamescript.ui.setting.KeyConfActivity
import com.fengxu.gamescript.util.MultiAnimUtils
import com.xuexiang.xui.utils.DensityUtils
import org.jetbrains.anko.sdk27.coroutines.onClick
import org.jetbrains.anko.sdk27.coroutines.onTouch
import kotlin.properties.Delegates

/**
 * 主悬浮窗控件
 */
class MainFloatViewWrapper {

    companion object{
        // 是否已经显示了一个悬浮窗
        var IsShow = false
        // 悬浮窗布局宽度
        private val FloatWidth = DensityUtils.dp2px(110F)
        // 悬浮窗布局高度
        private val FloatHeight = DensityUtils.dp2px(130F)
    }

    // 悬浮窗组件
     private var mView: View by Delegates.notNull()

    /**
     * 展开悬浮窗的控件
     */
    private val showView:View by lazy {
        mView.findViewById(R.id.flow_main_show)
    }

    /**
     * 显示脚本列表的控件
     */
    private val listView: View by lazy {
        mView.findViewById(R.id.flow_main_list)
    }

    /**
     * 停止是所有脚本的控件
     */
    private val stopAllView: View by lazy {
        mView.findViewById(R.id.flow_main_stop)
    }

    /**
     * 折叠悬浮窗的控件
     */
    private val keyConfView:View by lazy {
        mView.findViewById(R.id.flow_main_key)
    }

    /**
     * 是否显示已经显示了子菜单项
     */
    private var isShowSubItem = false

    /**
     * 是否可以移动悬浮窗的位置,在子菜单展开式不可移动
     */
    private var canMoveFloatWin = true

    // 是否可以切换子菜单
    private var canToggleSubMenu = true

    // 上下文
    private val mContext:Context

    // 窗口管理器
    private val windowManager: WindowManager

    constructor(applicationContext: Context){
        mContext = applicationContext
        windowManager = mContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        mView = View.inflate(applicationContext,R.layout.flow_main,null)
        initView()
    }

    /**
     * 初始化控件
     */
    @SuppressLint("ClickableViewAccessibility")
    private fun initView() {
        initTouch()
        // 打开子菜单
        showView.onClick {
            toggleSubItem()
        }
        // 打开脚本列表
        listView.onClick {
            FloatScriptQuickSelect(windowManager,mContext).showFloat()
            toggleSubItem()
        }
        // 关闭所有脚本
        stopAllView.onClick {
            GlobalData.getRunningScriptMap().forEach { (_, v) -> v.forceExit()  }
            toggleSubItem()
        }
        // 显示键位配置快捷选择栏
        keyConfView.onClick {
            FloatKeyConfQuickSelectView(mContext).showFloat()
            toggleSubItem()
        }
    }

    /**
     * 切换子菜单显示状态
     */
    private fun toggleSubItem(){
        if(!canToggleSubMenu) return
        isShowSubItem = !isShowSubItem
        canMoveFloatWin = !isShowSubItem
        val multiAnimUtils = MultiAnimUtils()
        showSubItemAnim(listView, isShowSubItem, multiAnimUtils)
        showSubItemAnim(stopAllView, isShowSubItem, multiAnimUtils)
        showSubItemAnim(keyConfView, isShowSubItem, multiAnimUtils)
        canToggleSubMenu = false
        multiAnimUtils.start()
        multiAnimUtils.allEndEvent = { canToggleSubMenu = true }
    }

    /**
     * 显示子菜单动画
     */
    private fun showSubItemAnim(view:View, isShow:Boolean, animUtils: MultiAnimUtils){
        setFloatViewParams(FloatWidth, FloatHeight)
        val lp = view.layoutParams as ConstraintLayout.LayoutParams
        val distance = lp.circleRadius
        val size = showView.width
        val distanceAnim = if(isShow){
            view.isVisible = true
            ValueAnimator.ofInt(0, lp.circleRadius)
        }else{
            ValueAnimator.ofInt(lp.circleRadius, 0)
        }
        distanceAnim.addUpdateListener {
            lp.circleRadius = it.animatedValue as Int
        }
        distanceAnim.doOnEnd {
            lp.circleRadius = distance
            view.layoutParams = lp
            setFloatViewParams(-2, -2)
            if(!isShow){view.isVisible = false}
        }
        val sizeAnim = if(isShow){
            ValueAnimator.ofInt(0, size)
        }else{
            ValueAnimator.ofInt(size, 0)
        }
        sizeAnim.addUpdateListener {
            lp.width = it.animatedValue as Int
            lp.height = it.animatedValue as Int
            view.layoutParams = lp
        }
        animUtils.addAnim(distanceAnim)
        animUtils.addAnim(sizeAnim)
    }

    /**
     * 初始化触摸修改悬浮窗位置事件
     */
    private fun initTouch(){
        var mTouchStartX = 0
        var mTouchStartY = 0
        showView.onTouch { v, event ->
            when(event.action){
                MotionEvent.ACTION_DOWN ->{
                    mTouchStartX = event.rawX.toInt()
                    mTouchStartY = event.rawY.toInt()
                }
                MotionEvent.ACTION_MOVE ->{
                    val xDiff = event.rawX.toInt() - mTouchStartX
                    val yDif = event.rawY.toInt() - mTouchStartY
                    mTouchStartX = event.rawX.toInt()
                    mTouchStartY = event.rawY.toInt()
                    if(!canMoveFloatWin) return@onTouch
                    val lp = mView.layoutParams as WindowManager.LayoutParams
                    lp.x += xDiff
                    lp.y += yDif
                    windowManager.updateViewLayout(mView, lp)
                }
                // 释放后自动贴左边
                MotionEvent.ACTION_UP ->{
                    val lp = mView.layoutParams as WindowManager.LayoutParams
                    val anim = if(lp.x > 50){
                        ValueAnimator.ofInt(lp.x, 0, 100, 0, 50, 0, 10, 0)
                    }else{
                        ValueAnimator.ofInt(lp.x, 0)
                    }
                    anim.addUpdateListener {
                        lp.x = anim.animatedValue as Int
                        windowManager.updateViewLayout(mView, lp)
                    }
                    anim.start()
                }
            }
        }
    }

    /**
     * 初始化悬浮窗
     */
    private fun initFloatWindow(){
        val lp = WindowManager.LayoutParams()
        lp.type = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
            WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
        }else{
            WindowManager.LayoutParams.TYPE_PHONE
        }
        lp.format = PixelFormat.RGBA_8888
        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON or
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS or
                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
        lp.gravity = Gravity.LEFT or Gravity.TOP
        lp.x = 0
        lp.y = (DensityUtils.getScreenMetrics(true).heightPixels * 0.1).toInt()
        lp.width = -2; lp.height = -2
        windowManager.addView(mView, lp)
    }

    /**
     * 设置悬浮窗的大小
     */
    private fun setFloatViewParams(width:Int, height:Int, x:Int = 0,y:Int=0) {
        val layoutParams = mView.layoutParams as WindowManager.LayoutParams
        layoutParams.width = width
        layoutParams.height = height
        layoutParams.x += x
        layoutParams.y += y
        windowManager.updateViewLayout(mView, layoutParams)
    }

    /**
     * 获取悬浮窗组件
     */
    fun getFloatView():View{
        return mView;
    }

    /**
     * 显示悬浮窗
     */
    fun show(){
        if(Conf.getConf().isStartFlowWin && !IsShow){
            initFloatWindow()
            IsShow = true
        }
    }

    /**
     * 关闭悬浮窗
     */
    fun hide(){
        windowManager.removeView(mView)
        IsShow = false
    }



}